package com.jie.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.jie.annotation.Decrypt;
import com.jie.annotation.Encrypt;
import com.jie.encryption.bean.EncryptBean;
import com.jie.encryption.utils.AesUtil;
import com.jie.encryption.utils.RsaUtil;
import org.apache.commons.codec.binary.Base64;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.security.PrivateKey;

/**
 * @author fanhf
 * @Description AES + RSA 加解密AOP处理
 * @date 2020-11-09 13:47
 */
@Aspect
@Component
public class DecryptAspect {

    private static final Logger log = LoggerFactory.getLogger(DecryptAspect.class);
    /**
     * 这里RSA加解密的时候需要根据公钥和私钥来进行加解密，真实的业务场景一般是从前端传过来公钥，私钥是随机获取的，我这里为了方便，就写死了。
     **/
    private static final PrivateKey PRIVATEKEY=RsaUtil.getPrivateKey();
    /**
     * Pointcut 切入点
     */
    @Pointcut("@annotation(com.jie.annotation.Decrypt)")
    public void safetyAspect() {}

    /**
     * 前置通知 必须要参数
     */
    @Around(value = "safetyAspect()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) {
        Object returnVal = null;
        try {
            // 获取切点方法的参数
            Object[] args = proceedingJoinPoint.getArgs();
            // 对切点方法的参数进行重新赋值
            EncryptBean encryptBean=null;
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof EncryptBean){
                    encryptBean= (EncryptBean) args[i];
                    break;
                }
            }
            //判断一下是不是post并且不为null
            if (null!=encryptBean){
                //对ase进行解密获取aseKey
                String aesKey = RsaUtil.decryptData(encryptBean.getAesData(),PRIVATEKEY);
                //根据获取的aesKey对加密json进行解密
                String dataJson = AesUtil.decrypt(encryptBean.getRsaData(), aesKey);
                //将存回encryption中
                encryptBean.setData(dataJson);
            }
            // 执行切点方法，并传递重新赋值后的参数列表
            returnVal = proceedingJoinPoint.proceed(args);
        } catch (Throwable e) {
            // 异常处理 ...
            log.error(e.getMessage());
            return JSONObject.parseObject("{ \"解密异常\": \"" +e.getMessage() + "\"}");
        }
        // 返回切点方法执行后的返回值
        return returnVal;
    }
}   

